home *** CD-ROM | disk | FTP | other *** search
- /* Expire old messages.
- * Inspired by 'expire.c' by Bernie Roehl.
- * Substantially rewritten for integration into KA9Q NOS,
- * WG7J v1.01 and later
- * by Johan. K. Reinalda, WG7J/PA3DIS, March/April 92
- *
- * Old bid expiry by WG7J, March 92
- */
- /* 'expire n' sets the expire interval for n hours.
- * Each time the timer goes off, a new process is started,
- * that expires the old messages...
- *
- * The control file '~/spool/expire.dat' contains lists of
- * filename age
- * where 'filename' is the name of the .txt file under '~/spool/mail'
- * containing the messages (without the .txt extension) and where
- * age = maximum age of message in days.
- *
- * If no age is given, the default age is 21 days.
- *
- * filename can be extended into subdirectories, and can have either
- * '/', '\' or '.' to indicate subdirectories.
- * filename should NOT have the ending '.txt'
- */
- #include <stdio.h>
- #include <stdlib.h>
- #ifdef MSDOS
- #include <dir.h>
- #include <dos.h>
- #endif
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <sys/timeb.h>
- #include <string.h>
- #include <ctype.h>
- #include <time.h>
- #include "global.h"
- #include "config.h"
- #include "timer.h"
- #include "proc.h"
- #include "bm.h"
- #include "files.h"
- #include "socket.h"
-
- #ifdef linux
- extern int unlink __ARGS((char *));
- #endif
-
- #ifdef UNIX
- #define mktime j_mktime
- #endif
-
- #ifndef __BORLANDC__
-
- time_t mktime(struct tm *);
-
- /* If you're using BC++ 2.0 or higher, you don't need this,
- * but TCC 2.0 doesn't have it... (But, TC++ v1.01 does)
- */
- /* Simple emulation of the mktime() call (sort-of works :-) )
- * doesn't do any error checking,
- * no timezone adjustments or value adjustments
- * Simply 'sort-a' calculates the number of seconds since 1970 - WG7J
- */
- time_t
- mktime(t)
- struct tm *t;
- {
- static int total[12]={0,31,59,90,120,151,181,212,243,273,304,334};
- int years;
- int leapyears;
- int days;
-
- /* time count start at jan 1, 1970, 00:00 hrs */
- years = t->tm_year - 70;
- /* adjust for leap-years */
- leapyears = (years + 2) / 4;
- if (!((years+70) & 3) && (t->tm_mon < 2))
- --leapyears; /* no extra day until 3/1 or after */
-
- days = years*365L + leapyears + total[t->tm_mon] + (t->tm_mday-1);
-
- return( days*86400L + t->tm_hour*3600L + t->tm_min*60L + t->tm_sec);
- }
-
- #endif
-
- /* Include the rest in #ifdef's, so we don't pull in the whole module
- * when we only have AT defined and NOT EXPIRE !
- * (since these are the two modules that needs the surrogate mktime()
- * if compiling with Turbo C 2.0 )
- */
- #ifdef EXPIRY
-
- /* Default expiry values: */
- #define DEFAULT_AGE 21 /* 21 days from arrival date */
- #define MSPHOUR (1000L*60L*60L)
- static struct timer Expiretimer;
-
- static void Expireprocess __ARGS((int a,void *v1,void *v2));
- static void Expiretick __ARGS((void *));
- static void expire __ARGS((char *,int));
- static void Oldbidtick __ARGS((void *p));
-
- int
- #ifdef PROTOTYPES
- doexpire(int argc,char **argv,void *p)
- #else
- doexpire(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- #endif
- {
- if(argc < 2) {
- tprintf("timer: %lu/%lu hrs\n",
- read_timer(&Expiretimer)/MSPHOUR,
- dur_timer(&Expiretimer)/MSPHOUR);
- return 0;
- }
- if(*argv[1] == 'n') {
- Expiretick(NULL);
- return 0;
- }
- /* set the timer */
- stop_timer(&Expiretimer); /* Just in case */
- Expiretimer.func = (void (*)__FARGS((void*)))Expiretick;/* what to call on timeout */
- Expiretimer.arg = NULL; /* dummy value */
- set_timer(&Expiretimer,atol(argv[1])*MSPHOUR); /* set timer duration */
- start_timer(&Expiretimer);
- return 0;
- }
-
- void
- Expiretick(p)
- void *p;
- {
- start_timer(&Expiretimer);
- /* Spawn off the process */
- newproc("Expiry", 1024, Expireprocess, 0, NULL, NULL, 0);
- }
-
- static void
- Expireprocess(a,v1,v2)
- int a;
- void *v1, *v2;
- {
- char line[80];
- int age = DEFAULT_AGE;
- char *cp;
- FILE *ctl;
-
- if ((ctl = fopen(Expirefile, "r")) == NULLFILE) {
- return;
- }
- /* read lines from the control file */
- while(fgets(line, sizeof(line), ctl) != NULLCHAR) {
- pwait(NULL); /* be nice */
- if((*line == '#') || (*line == '\n')) /* comment or blank line */
- continue;
- rip(line);
- /* terminate area name */
- if((cp=strchr(line, ' ')) != NULLCHAR) {
- /* there is age info */
- *cp++ = '\0';
- age = atoi(cp);
- }
- pwait(NULL); /* be nice */
- expire(line,age);
- }
- fclose(ctl);
- }
-
- void
- expire(filename,age)
- char *filename;
- int age;
- {
- char file[128], bckfile[128],*cp;
- char buf[128];
- int keep,copy,expired;
- FILE *old;
- FILE *new;
- long pos;
- time_t now;
- time_t then;
- struct tm t;
-
- /* first replace all '.' and '\' with '/' */
- for(cp=filename;*cp != '\0'; cp++)
- if((*cp == '.') || (*cp == '\\'))
- *cp = '/';
-
- if (mlock(Mailspool,filename)) {
- /* can't get a lock */
- return;
- }
-
- /* now append the 'home dir' in front of name */
- strcpy(file,Mailspool);
- strcat(file,"/");
- strcat(file, filename);
-
- /* get the name for the backup file */
- strcpy(bckfile,file);
- strcat(bckfile,".bak");
- strcat(file,".txt");
-
- /* rename the file */
- unlink(bckfile);
- if(rename(file,bckfile) == -1) {
- rmlock(Mailspool, filename);
- return;
- }
- /* open the backup file and the new txt file */
- if((old = fopen(bckfile, "rt")) == NULLFILE) {
- rmlock(Mailspool, filename);
- return;
- }
- if((new = fopen(file, "wt")) == NULLFILE) {
- rmlock(Mailspool, filename);
- return;
- }
- time(&now);
- copy = expired = 0;
- pos=ftell(old);
- while(fgets(buf,sizeof(buf),old) != NULLCHAR) {
- pwait(NULL);
- if (!strncmp(buf,"From ",5)) {
- /* start of next message; at this point
- * pos has the offset of the start of this line
- */
- keep = copy = 0;
- while(fgets(buf,sizeof(buf),old) != NULLCHAR) {
- if(*buf == '\n')
- break; /* end of headers */
- if(htype(buf) == DATE) {
- /* find age from ARPA style date */
- /* check to see if there is a "Day, " field */
- if((cp=strchr(buf,',')) != NULLCHAR) {
- /* probably standard ARPA style header */
- cp = &buf[11]; /* get past header and DAY field */
- } else {
- /* probably a NNTP style message, that has no
- * "Day, " part in the date line
- */
- cp = &buf[6];
- }
- /* now we should be at the start of the
- * "14 Apr 92 08:14:32" string
- */
- if(strlen(cp) < 17) /* Too short */
- break;
- t.tm_mday = atoi(cp);
- if(*(++cp) != ' ')
- ++cp;
- ++cp;
- for(t.tm_mon=0; t.tm_mon < 12; t.tm_mon++)
- if(strnicmp(Months[t.tm_mon],cp,3) == 0)
- break;
- if(t.tm_mon == 12)
- break; /* invalid */
- t.tm_year = atoi(cp+4);
- t.tm_hour = atoi(cp+7);
- t.tm_min = atoi(cp+10);
- t.tm_sec = atoi(cp+13);
- /*
- printf("%d %d %d, %d %d %d\n",
- t.tm_mday,t.tm_mon,t.tm_year,t.tm_hour,t.tm_min,t.tm_sec);
- */
- if((then=mktime(&t)) == -1)
- break; /* invalid, delete */
- /* Now check against age */
- if(now-then < (age*86400L))
- keep = 1;
- break;
- }
- }
- if(keep) {
- /* rewind to start of this message,
- * write from-line and copy the rest
- */
- fseek(old,pos,SEEK_SET);
- fgets(buf,sizeof(buf),old);
- fputs(buf,new);
- copy = 1;
- } else
- expired++;
- } else { /* Any none 'from' line */
- if(copy)
- /* we're in the middle of copying a message */
- fputs(buf,new);
- }
- pos=ftell(old);
- }
- fclose(new);
- fclose(old);
- rmlock(Mailspool,filename);
- if(expired)
- log(-1,"Expired: %d in %s",expired,filename);
- }
-
-
- /******************************************************************/
- /* This program will deleted old BID's from the history file,
- * after making a backup copy.
- *
- * Eg. 'oldbids 24 30' will try to delete all bids older then 30 days
- * every 24 hours.
- * 'oldbids now' will do it now, with set value of age.
- *
- * Copyright 1992, Johan. K. Reinalda, WG7J/PA3DIS
- * email : johan@ece.orst.edu
- * packet: wg7j@wg7j.or.usa.na
- *
- * Any part of this source may be freely distributed for none-commercial,
- * amateur radio use only, as long as credit is given to the author.
- *
- * v1.0 920325
- */
- static struct timer Oldbidtimer;
- static int Oldbid_age = 30;
-
- static
- void
- Oldbidtick(p)
- void *p;
- {
- int expired = 0;
- char *cp;
- FILE *old, *new;
- time_t now;
- time_t age;
- time_t bidtime;
- #define LEN 80
- char oldfile[LEN];
- char buf[LEN];
-
- stop_timer(&Oldbidtimer);
-
- /* delete a previous backup and rename current history file */
- strcpy(oldfile,Historyfile);
- strcat(oldfile,".bak");
- unlink(oldfile);
- if(rename(Historyfile,oldfile) == -1) {
- tputs("oldbid: can't rename history file\n");
- return;
- }
-
- /* open backup for reading, create new history file */
- if((old = fopen(oldfile,"rt")) == NULL) {
- tputs("oldbid: error opening history.bak\n");
- return;
- }
- if((new = fopen(Historyfile,"wt")) == NULL) {
- tputs("oldbid: error creating history file\n");
- return;
- }
-
- now = time(&now);
- age = (time_t)(Oldbid_age*86400L);
-
- while(fgets(buf,LEN,old) != NULL) {
- if((cp=strchr(buf,'\n')) != NULLCHAR)
- *cp = '\0';
- if((cp=strchr(buf,' ')) != NULLCHAR) {
- /*found one with timestamp*/
- *cp = '\0';
- cp++; /* now points to timestamp */
- if((bidtime = atol(cp)) == 0L)
- /*something wrong, re-stamp */
- fprintf(new,"%s %ld\n",buf,now);
- else {
- /* Has this one expired yet ? */
- if(now - bidtime < age)
- fprintf(new,"%s %ld\n",buf,bidtime);
- else
- expired++;
- }
- } else {
- /* This is an old one without time stamp,
- * add to the new file with current time as timestamp
- */
- fprintf(new,"%s %ld\n",buf,now);
- }
- }
- fclose(old);
- fclose(new);
- if(expired)
- log(-1,"Oldbids: %d expired",expired);
- start_timer(&Oldbidtimer);
- return;
- }
-
- int
- #ifdef PROTOTYPES
- dooldbids(int argc,char **argv,void *p)
- #else
- dooldbids(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- #endif
- {
- if(argc < 2){
- tprintf("timer: %lu/%lu hrs; age: %d days\n",
- read_timer(&Oldbidtimer)/MSPHOUR,
- dur_timer(&Oldbidtimer)/MSPHOUR,
- Oldbid_age);
- return 0;
- }
- if(*argv[1] == 'n') {
- Oldbidtick(NULL);
- return 0;
- }
- /* set the timer */
- stop_timer(&Oldbidtimer); /* Just in case */
- Oldbidtimer.func = (void (*)__FARGS((void*)))Oldbidtick;/* what to call on timeout */
- Oldbidtimer.arg = NULL; /* dummy value */
- set_timer(&Oldbidtimer,atol(argv[1])*MSPHOUR); /* set timer duration */
- if(argc > 2)
- Oldbid_age = atoi(argv[2]);
- Oldbidtick(NULL); /* Do one now and start it all!*/
- return 0;
- }
-
- #endif /* EXPIRE */
-